﻿using Microsoft.Data.SqlClient;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using RepoDb.IntegrationTests.Models;
using RepoDb.IntegrationTests.Setup;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace RepoDb.IntegrationTests.Types.Others
{
    [TestClass]
    public class SqlConnectionOthersTest
    {
        [TestInitialize]
        public void Initialize()
        {
            Database.Initialize();
            Cleanup();
        }

        [TestCleanup]
        public void Cleanup()
        {
            Database.Cleanup();
        }

        #region <TEntity>

        //[TestMethod]
        //public void TestSqlConnectionOthersCrud()
        //{
        //    // Setup
        //    var entity = new OthersClass
        //    {
        //        SessionId = Guid.NewGuid(),
        //        ColumnHierarchyId = "/",
        //        ColumnSqlVariant = "This is variant!",
        //        ColumnUniqueIdentifier = Guid.NewGuid(),
        //        ColumnXml = "<xml><person><id>1</id><name>Michael</name></person><person><id>2</id><name>RepoDb</name></person></xml>"
        //    };
        //
        //    using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
        //    {
        //        // Act Insert
        //        var id = connection.Insert(entity);
        //
        //        // Act Query
        //        var data = connection.Query<OthersClass>(e => e.SessionId == (Guid)id).FirstOrDefault();
        //
        //        // Assert
        //        Assert.IsNotNull(data);
        //        Assert.AreEqual(entity.ColumnHierarchyId.ToString(), data.ColumnHierarchyId?.ToString());
        //        Assert.AreEqual(entity.ColumnSqlVariant, data.ColumnSqlVariant);
        //        Assert.AreEqual(entity.ColumnUniqueIdentifier, data.ColumnUniqueIdentifier);
        //        Assert.AreEqual(entity.ColumnXml, data.ColumnXml);
        //    }
        //}

        [TestMethod]
        public void TestSqlConnectionOthersNullCrud()
        {
            // Setup
            var entity = new OthersClass
            {
                SessionId = Guid.NewGuid(),
                ColumnHierarchyId = null,
                ColumnSqlVariant = null,
                ColumnUniqueIdentifier = null,
                ColumnXml = null
            };

            using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
            {
                // Act Insert
                var id = connection.Insert(entity);

                // Act Query
                var data = connection.Query<OthersClass>(e => e.SessionId == (Guid)id).FirstOrDefault();

                // Assert
                Assert.IsNotNull(data);
                Assert.IsNull(data.ColumnHierarchyId);
                Assert.IsNull(data.ColumnSqlVariant);
                Assert.IsNull(data.ColumnUniqueIdentifier);
                Assert.IsNull(data.ColumnXml);
            }
        }

        //[TestMethod]
        //public void TestSqlConnectionOthersMappedCrud()
        //{
        //    // Setup
        //    var entity = new OthersMapClass
        //    {
        //        SessionId = Guid.NewGuid(),
        //        ColumnHierarchyIdMapped = "/",
        //        ColumnSqlVariantMapped = "This is variant!",
        //        ColumnUniqueIdentifierMapped = Guid.NewGuid(),
        //        ColumnXmlMapped = "<xml><person><id>1</id><name>Michael</name></person><person><id>2</id><name>RepoDb</name></person></xml>"
        //    };
        //
        //    using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
        //    {
        //        // Act Insert
        //        var id = connection.Insert(entity);
        //
        //        // Act Query
        //        var data = connection.Query<OthersMapClass>(e => e.SessionId == (Guid)id).FirstOrDefault();
        //
        //        // Assert
        //        Assert.IsNotNull(data);
        //        Assert.AreEqual(entity.ColumnHierarchyIdMapped.ToString(), data.ColumnHierarchyIdMapped?.ToString());
        //        Assert.AreEqual(entity.ColumnSqlVariantMapped, data.ColumnSqlVariantMapped);
        //        Assert.AreEqual(entity.ColumnUniqueIdentifierMapped, data.ColumnUniqueIdentifierMapped);
        //        Assert.AreEqual(entity.ColumnXmlMapped, data.ColumnXmlMapped);
        //    }
        //}

        [TestMethod]
        public void TestSqlConnectionOthersMappedNullCrud()
        {
            // Setup
            var entity = new OthersMapClass
            {
                SessionId = Guid.NewGuid(),
                ColumnHierarchyIdMapped = null,
                ColumnSqlVariantMapped = null,
                ColumnUniqueIdentifierMapped = null,
                ColumnXmlMapped = null
            };

            using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
            {
                // Act Insert
                var id = connection.Insert(entity);

                // Act Query
                var data = connection.Query<OthersMapClass>(e => e.SessionId == (Guid)id).FirstOrDefault();

                // Assert
                Assert.IsNotNull(data);
                Assert.IsNull(data.ColumnHierarchyIdMapped);
                Assert.IsNull(data.ColumnSqlVariantMapped);
                Assert.IsNull(data.ColumnUniqueIdentifierMapped);
                Assert.IsNull(data.ColumnXmlMapped);
            }
        }

        //[TestMethod]
        //public async Task TestSqlConnectionOthersCrudAsync()
        //{
        //    // Setup
        //    var entity = new OthersClass
        //    {
        //        SessionId = Guid.NewGuid(),
        //        ColumnHierarchyId = "/",
        //        ColumnSqlVariant = "This is variant!",
        //        ColumnUniqueIdentifier = Guid.NewGuid(),
        //        ColumnXml = "<xml><person><id>1</id><name>Michael</name></person><person><id>2</id><name>RepoDb</name></person></xml>"
        //    };
        //
        //    using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
        //    {
        //        // Act Insert
        //        var insertResult = connection.InsertAsync(entity);
        //        var id = insertResult;
        //
        //        // Act Query
        //        var queryResult = connection.QueryAsync<OthersClass>(e => e.SessionId == (Guid)id);
        //        var data = queryResult.FirstOrDefault();
        //
        //        // Assert
        //        Assert.IsNotNull(data);
        //        Assert.AreEqual(entity.ColumnHierarchyId.ToString(), data.ColumnHierarchyId?.ToString());
        //        Assert.AreEqual(entity.ColumnSqlVariant, data.ColumnSqlVariant);
        //        Assert.AreEqual(entity.ColumnUniqueIdentifier, data.ColumnUniqueIdentifier);
        //        Assert.AreEqual(entity.ColumnXml, data.ColumnXml);
        //    }
        //}

        [TestMethod]
        public async Task TestSqlConnectionOthersNullCrudAsync()
        {
            // Setup
            var entity = new OthersClass
            {
                SessionId = Guid.NewGuid(),
                ColumnHierarchyId = null,
                ColumnSqlVariant = null,
                ColumnUniqueIdentifier = null,
                ColumnXml = null
            };

            using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
            {
                // Act Insert
                var insertResult = connection.InsertAsync(entity);
                var id = await insertResult;

                // Act Query
                var queryResult = await connection.QueryAsync<OthersClass>(e => e.SessionId == (Guid)id);
                var data = queryResult.FirstOrDefault();

                // Assert
                Assert.IsNotNull(data);
                Assert.IsNull(data.ColumnHierarchyId);
                Assert.IsNull(data.ColumnSqlVariant);
                Assert.IsNull(data.ColumnUniqueIdentifier);
                Assert.IsNull(data.ColumnXml);
            }
        }

        //[TestMethod]
        //public async Task TestSqlConnectionOthersMappedCrudAsync()
        //{
        //    // Setup
        //    var entity = new OthersMapClass
        //    {
        //        SessionId = Guid.NewGuid(),
        //        ColumnHierarchyIdMapped = "/",
        //        ColumnSqlVariantMapped = "This is variant!",
        //        ColumnUniqueIdentifierMapped = Guid.NewGuid(),
        //        ColumnXmlMapped = "<xml><person><id>1</id><name>Michael</name></person><person><id>2</id><name>RepoDb</name></person></xml>"
        //    };
        //
        //    using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
        //    {
        //        // Act Insert
        //        var insertResult = connection.InsertAsync(entity);
        //        var id = insertResult;
        //
        //        // Act Query
        //        var queryResult = connection.QueryAsync<OthersMapClass>(e => e.SessionId == (Guid)id);
        //        var data = queryResult.FirstOrDefault();
        //
        //        // Assert
        //        Assert.IsNotNull(data);
        //        Assert.AreEqual(entity.ColumnHierarchyIdMapped.ToString(), data.ColumnHierarchyIdMapped?.ToString());
        //        Assert.AreEqual(entity.ColumnSqlVariantMapped, data.ColumnSqlVariantMapped);
        //        Assert.AreEqual(entity.ColumnUniqueIdentifierMapped, data.ColumnUniqueIdentifierMapped);
        //        Assert.AreEqual(entity.ColumnXmlMapped, data.ColumnXmlMapped);
        //    }
        //}

        [TestMethod]
        public async Task TestSqlConnectionOthersMappedNullCrudAsync()
        {
            // Setup
            var entity = new OthersMapClass
            {
                SessionId = Guid.NewGuid(),
                ColumnHierarchyIdMapped = null,
                ColumnSqlVariantMapped = null,
                ColumnUniqueIdentifierMapped = null,
                ColumnXmlMapped = null
            };

            using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
            {
                // Act Insert
                var insertResult = connection.InsertAsync(entity);
                var id = await insertResult;

                // Act Query
                var queryResult = await connection.QueryAsync<OthersMapClass>(e => e.SessionId == (Guid)id);
                var data = queryResult.FirstOrDefault();

                // Assert
                Assert.IsNotNull(data);
                Assert.IsNull(data.ColumnHierarchyIdMapped);
                Assert.IsNull(data.ColumnSqlVariantMapped);
                Assert.IsNull(data.ColumnUniqueIdentifierMapped);
                Assert.IsNull(data.ColumnXmlMapped);
            }
        }

        #endregion

        #region (TableName)

        //[TestMethod]
        //public void TestSqlConnectionOthersCrudViaTableName()
        //{
        //    // Setup
        //    var entity = new
        //    {
        //        SessionId = Guid.NewGuid(),
        //        ColumnHierarchyId = (object)"/",
        //        ColumnSqlVariant = "This is variant!",
        //        ColumnUniqueIdentifier = Guid.NewGuid(),
        //        ColumnXml = "<xml><person><id>1</id><name>Michael</name></person><person><id>2</id><name>RepoDb</name></person></xml>"
        //    };
        //
        //    using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
        //    {
        //        // Act Insert
        //        var id = connection.Insert(ClassMappedNameCache.Get<OthersClass>(), entity);
        //
        //        // Act Query
        //        var data = connection.Query(ClassMappedNameCache.Get<OthersClass>(), new { SessionId = (Guid)id }).FirstOrDefault();
        //
        //        // Assert
        //        Assert.IsNotNull(data);
        //        Assert.AreEqual(entity.ColumnHierarchyId.ToString(), data.ColumnHierarchyId?.ToString());
        //        Assert.AreEqual(entity.ColumnSqlVariant, data.ColumnSqlVariant);
        //        Assert.AreEqual(entity.ColumnUniqueIdentifier, data.ColumnUniqueIdentifier);
        //        Assert.AreEqual(entity.ColumnXml, data.ColumnXml);
        //    }
        //}

        [TestMethod]
        public void TestSqlConnectionOthersNullCrudViaTableName()
        {
            // Setup
            var entity = new
            {
                SessionId = Guid.NewGuid(),
                ColumnHierarchyId = (object)null,
                ColumnSqlVariant = (string)null,
                ColumnUniqueIdentifier = (Guid?)null,
                ColumnXml = (string)null
            };

            using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
            {
                // Act Insert
                var id = connection.Insert(ClassMappedNameCache.Get<OthersClass>(), entity);

                // Act Query
                var data = connection.Query(ClassMappedNameCache.Get<OthersClass>(), new { SessionId = (Guid)id }).FirstOrDefault();

                // Assert
                Assert.IsNotNull(data);
                Assert.IsNull(data.ColumnHierarchyId);
                Assert.IsNull(data.ColumnSqlVariant);
                Assert.IsNull(data.ColumnUniqueIdentifier);
                Assert.IsNull(data.ColumnXml);
            }
        }

        //[TestMethod]
        //public async Task TestSqlConnectionOthersCrudViaAsyncViaTableName()
        //{
        //    // Setup
        //    var entity = new
        //    {
        //        SessionId = Guid.NewGuid(),
        //        ColumnHierarchyId = (object)"/",
        //        ColumnSqlVariant = "This is variant!",
        //        ColumnUniqueIdentifier = Guid.NewGuid(),
        //        ColumnXml = "<xml><person><id>1</id><name>Michael</name></person><person><id>2</id><name>RepoDb</name></person></xml>"
        //    };
        //
        //    using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
        //    {
        //        // Act Insert
        //        var insertResult = connection.InsertAsync(ClassMappedNameCache.Get<OthersClass>(), entity);
        //        var id = insertResult;
        //
        //        // Act Query
        //        var queryResult = connection.QueryAsync(ClassMappedNameCache.Get<OthersClass>(), new { SessionId = (Guid)id });
        //        var data = queryResult.FirstOrDefault();
        //
        //        // Assert
        //        Assert.IsNotNull(data);
        //        Assert.AreEqual(entity.ColumnHierarchyId.ToString(), data.ColumnHierarchyId?.ToString());
        //        Assert.AreEqual(entity.ColumnSqlVariant, data.ColumnSqlVariant);
        //        Assert.AreEqual(entity.ColumnUniqueIdentifier, data.ColumnUniqueIdentifier);
        //        Assert.AreEqual(entity.ColumnXml, data.ColumnXml);
        //    }
        //}

        [TestMethod]
        public async Task TestSqlConnectionOthersNullCrudViaAsyncViaTableName()
        {
            // Setup
            var entity = new
            {
                SessionId = Guid.NewGuid(),
                ColumnHierarchyId = (object)null,
                ColumnSqlVariant = (string)null,
                ColumnUniqueIdentifier = (Guid?)null,
                ColumnXml = (string)null
            };

            using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb))
            {
                // Act Insert
                var insertResult = connection.InsertAsync(ClassMappedNameCache.Get<OthersClass>(), entity);
                var id = await insertResult;

                // Act Query
                var queryResult = await connection.QueryAsync(ClassMappedNameCache.Get<OthersClass>(), new { SessionId = (Guid)id });
                var data = queryResult.FirstOrDefault();

                // Assert
                Assert.IsNotNull(data);
                Assert.IsNull(data.ColumnHierarchyId);
                Assert.IsNull(data.ColumnSqlVariant);
                Assert.IsNull(data.ColumnUniqueIdentifier);
                Assert.IsNull(data.ColumnXml);
            }
        }

        #endregion
    }
}
